#include <stdio.h>              // C/C++库：标准输入输出。printf();

#include "ohos_init.h"          // OH公共基础库：SYS_RUN();
#include "hi_gpio.h"            // 海思hi3861SDK：hi_gpio_init();hi_gpio_set_dir();hi_gpio_set_ouput_val();HI_GPIO_DIR_OUT;HI_GPIO_VALUE0
#include "hi_io.h"              // 海思hi3861SDK：hi_io_set_func();HI_IO_NAME_GPIO_0;
#include "hi_pwm.h"             // 海思hi3861SDK：hi_pwm_init();hi_pwm_set_clock();hi_pwm_start();HI_PWM_PORT_PWM0;PWM_CLK_XTAL;hi_u16;
#include "hi_adc.h"             // 海思hi3861SDK：hi_adc_read();
#include "iot_pwm.h"            // IOT硬件子系统：IoTPwmInit()

#include "read_senser.h"

/**
 * @brief GPIO初始化
 * 
 */
void GpioInit(void){
    printf("GpioInit().\n");
    hi_gpio_init();                                             //GPIO模块初始化
    hi_gpio_set_dir(HI_IO_NAME_GPIO_10, HI_GPIO_DIR_OUT);                //设置某个GPIO管脚方向
    hi_gpio_set_dir(HI_IO_NAME_GPIO_0, HI_GPIO_DIR_IN);                //设置某个GPIO管脚方向
    hi_gpio_set_dir(HI_IO_NAME_GPIO_1, HI_GPIO_DIR_IN);                //设置某个GPIO管脚方向
    // hi_gpio_set_dir(LED_Gpio, HI_GPIO_DIR_OUT);                 //设置某个GPIO管脚方向

    hi_io_set_func(HI_IO_NAME_GPIO_9, HI_IO_FUNC_GPIO_9_PWM0_OUT);      //设置GPIO引脚复用
    hi_pwm_init(HI_PWM_PORT_PWM0);
}

/**
 * @brief 获取运行状态，输入输出电流电压
 * 
 */
void GetState(Report_Data *report_data){
    float *data;
    hi_adc_read(0, &data, HI_ADC_EQU_MODEL_8, HI_ADC_CUR_BAIS_DEFAULT, 0);      // ADC通道0，是A12，输入电压（太阳能端）
    // 将ADC读取到的码字转换为电压，并四舍五入保留2位小数
    // float involtage = (int)(100.0*(hi_adc_convert_to_voltage(data)/0.0248)+0.5)/100.0;
    int involtage = (int)(hi_adc_convert_to_voltage(data)/0.000248);
    report_data->in_voltage = involtage;

    hi_adc_read(2, &data, HI_ADC_EQU_MODEL_8, HI_ADC_CUR_BAIS_DEFAULT, 0);      // ADC通道2，是A5，输出电压（储能端）
    // float outvoltage = (int)(100.0*(hi_adc_convert_to_voltage(data)/0.04)+0.5)/100.0;
    int outvoltage = (int)(hi_adc_convert_to_voltage(data)/0.00004);
    report_data->out_voltage = outvoltage;

    int incurrent = (int)23.4567;
    report_data->in_current = incurrent;

    printf("输入电压：%d，输出电压：%d，当前电流：%d\n",involtage,outvoltage,incurrent);
}

void BuckControl(hi_bool state,hi_u16 duty){
    if (state)
    {
        printf("true.\n");
        hi_gpio_set_ouput_val(HI_IO_NAME_GPIO_10,HI_GPIO_VALUE1);
        IoTPwmStart(HI_PWM_PORT_PWM0, duty, 39000);//输出频率39KHz
    }else{
        printf("false.\n");
        hi_gpio_set_ouput_val(HI_IO_NAME_GPIO_10,HI_GPIO_VALUE0);
        IoTPwmStart(HI_PWM_PORT_PWM0, duty, 39000);
    }
}

hi_u8 constrain_hi_u8(hi_u8 amt, hi_u8 low, hi_u8 high){        //限幅函数
    return ((amt)<(low)?(low):((amt)>(high)?(high):(amt)));
}

// void predictivePWM(){                                                                //PREDICTIVE PWM ALGORITHM 预测PWM算法
//   if(voltageInput<=0){PPWM=0;}                                                       //Prevents Indefinite Answer when voltageInput is zero 当电压输入为零时，防止无限期回答
//   else{PPWM =(PPWM_margin*pwmMax*voltageOutput)/(100.00*voltageInput);}              //Compute for predictive PWM Floor and store in variable 计算预测PWM地板和存储在变量
//   PPWM = constrain(PPWM,0,pwmMaxLimited);
//   printf("PPWM:%d",PPWM);
// }
/**
 * @brief 预测Buck占空比
 * 
 */
static void PredictiveBuckDuty(void){
    // InitBuckDuty = 100*OutVoltage/InVoltage;
    // InitBuckDuty = constrain_hi_u8(InitBuckDuty,1,99);
    // printf("初始化Buck降压电压占空比：%d。\n",InitBuckDuty);

}